home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / ax25dump.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  6KB  |  275 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "ax25.h"
  5. #include "timer.h"
  6. #include "lapb.h"
  7. #include "trace.h"
  8. #ifdef    UNIX
  9. #include <memory.h>
  10. #endif
  11.  
  12. extern FILE *trfp;
  13.  
  14. /* Dump an AX.25 packet header */
  15. /*ARGSUSED*/
  16. ax25_dump(bpp,check)
  17. struct mbuf **bpp;
  18. int check;    /* Not used */
  19. {
  20.     char *decode_type();
  21.     char tmp[20];
  22.     char control,pid;
  23.     int16 type,ftype();
  24.     struct ax25 hdr;
  25.     struct ax25_addr *hp;
  26.  
  27.     fprintf(trfp,"AX25: ");
  28.     /* Extract the address header */
  29.     if(ntohax25(&hdr,bpp) < 0){
  30.         /* Something wrong with the header */
  31.         fprintf(trfp," bad header!\n");
  32.         return;
  33.     }
  34.     pax25(tmp,&hdr.source);
  35.     fprintf(trfp,"%s",tmp);
  36.     pax25(tmp,&hdr.dest);
  37.     fprintf(trfp,"->%s",tmp);
  38.     if(hdr.ndigis > 0){
  39.         fprintf(trfp," v");
  40.         for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
  41.             /* Print digi string */
  42.             pax25(tmp,hp);
  43.             fprintf(trfp," %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
  44.         }
  45.     }
  46.     if(pullup(bpp,&control,1) != 1)
  47.         return;
  48.  
  49.     putchar(' ');
  50.     type = ftype(control);
  51.     fprintf(trfp,"%s",decode_type(type));
  52.     /* Dump poll/final bit */
  53.     if(control & PF){
  54.         switch(hdr.cmdrsp){
  55.         case COMMAND:
  56.             fprintf(trfp,"(P)");
  57.             break;
  58.         case RESPONSE:
  59.             fprintf(trfp,"(F)");
  60.             break;
  61.         default:
  62.             fprintf(trfp,"(P/F)");
  63.             break;
  64.         }
  65.     }
  66.     /* Dump sequence numbers */
  67.     if((type & 0x3) != U)    /* I or S frame? */
  68.         fprintf(trfp," NR=%d",(control>>5)&7);
  69.     if(type == I || type == UI){    
  70.         if(type == I)
  71.             fprintf(trfp," NS=%d",(control>>1)&7);
  72.         /* Decode I field */
  73.         if(pullup(bpp,&pid,1) == 1){    /* Get pid */
  74.             switch(pid & (PID_FIRST | PID_LAST)){
  75.             case PID_FIRST:
  76.                 fprintf(trfp," First frag");
  77.                 break;
  78.             case PID_LAST:
  79.                 fprintf(trfp," Last frag");
  80.                 break;
  81.             case PID_FIRST|PID_LAST:
  82.                 break;    /* Complete message, say nothing */
  83.             case 0:
  84.                 fprintf(trfp," Middle frag");
  85.                 break;
  86.             }
  87.             fprintf(trfp," pid=");
  88.             switch(pid & 0x3f){
  89.             case PID_ARP:
  90.                 fprintf(trfp,"ARP\n");
  91.                 break;
  92.             case PID_NETROM:
  93.                 fprintf(trfp,"NET/ROM\n");
  94.                 break;
  95.             case PID_IP:
  96.                 fprintf(trfp,"IP\n");
  97.                 break;
  98.             case PID_NO_L3:
  99.                 fprintf(trfp,"Text\n");
  100.                 break;
  101.             default:
  102.                 fprintf(trfp,"0x%x\n",pid);
  103.             }
  104.             /* Only decode frames that are the first in a
  105.              * multi-frame sequence
  106.              */
  107.             switch(pid & (PID_PID | PID_FIRST)){
  108.             case PID_ARP | PID_FIRST:
  109.                 arp_dump(bpp);
  110.                 break;
  111.             case PID_IP | PID_FIRST:
  112.                 /* Only checksum complete frames */
  113.                 ip_dump(bpp,pid & PID_LAST);
  114.                 break;
  115.             case PID_NETROM | PID_FIRST:
  116.                 netrom_dump(bpp);
  117.                 break;
  118.             }
  119.         }
  120.     } else if(type == FRMR && pullup(bpp,tmp,3) == 3){
  121.         fprintf(trfp,": %s",decode_type(ftype(tmp[0])));
  122.         fprintf(trfp," Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
  123.             (tmp[1] >> 1) & MMASK);
  124.         if(tmp[2] & W)
  125.             fprintf(trfp," Invalid control field");
  126.         if(tmp[2] & X)
  127.             fprintf(trfp," Illegal I-field");
  128.         if(tmp[2] & Y)
  129.             fprintf(trfp," Too-long I-field");
  130.         if(tmp[2] & Z)
  131.             fprintf(trfp," Invalid seq number");
  132.         fprintf(trfp,"\n");
  133.     } else
  134.         fprintf(trfp,"\n");
  135.  
  136.     fflush(stdout);
  137. }
  138. /* Display NET/ROM network and transport headers */
  139. static
  140. netrom_dump(bpp)
  141. struct mbuf **bpp;
  142. {
  143.     struct ax25_addr src,dest;
  144.     char x;
  145.     char tmp[16];
  146.     char thdr[5];
  147.     register i;
  148.  
  149.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  150.         return;
  151.     /* See if it is a routing broadcast */
  152.     if(uchar(*(*bpp)->data) == 0xff) {
  153.         pullup(bpp,tmp,1);        /* Signature */
  154.         pullup(bpp,tmp,ALEN);
  155.         tmp[ALEN] = '\0';
  156.         fprintf(trfp,"NET/ROM Routing: %s\n",tmp);
  157.         for(i = 0;i < 11;i++) {
  158.             if (pullup(bpp,tmp,AXALEN) < AXALEN)
  159.                 break;
  160.             memcpy(src.call,tmp,ALEN);
  161.             src.ssid = tmp[ALEN];
  162.             pax25(tmp,&src);
  163.             fprintf(trfp,"        %12s",tmp);
  164.             pullup(bpp,tmp,ALEN);
  165.             tmp[ALEN] = '\0';
  166.             fprintf(trfp,"%8s",tmp);
  167.             pullup(bpp,tmp,AXALEN);
  168.             memcpy(src.call,tmp, ALEN);
  169.             src.ssid = tmp[ALEN];
  170.             pax25(tmp,&src);
  171.             fprintf(trfp,"    %12s", tmp);
  172.             pullup(bpp,tmp,1);
  173.             fprintf(trfp,"    %3u\n", (unsigned)uchar(tmp[0]));
  174.         }
  175.         return;
  176.     }
  177.     /* Decode network layer */
  178.     pullup(bpp,tmp,AXALEN);
  179.     memcpy(src.call,tmp,ALEN);
  180.     src.ssid = tmp[ALEN];
  181.     pax25(tmp,&src);
  182.     fprintf(trfp,"NET/ROM: %s",tmp);
  183.  
  184.     pullup(bpp,tmp,AXALEN);
  185.     memcpy(dest.call,tmp,ALEN);
  186.     dest.ssid = tmp[ALEN];
  187.     pax25(tmp,&dest);
  188.     fprintf(trfp,"->%s",tmp);
  189.  
  190.     pullup(bpp,&x,1);
  191.     fprintf(trfp," ttl %d\n",uchar(x));
  192.  
  193.     /* Read first five bytes of "transport" header */
  194.     pullup(bpp,thdr,5);
  195.     switch(thdr[4] & 0xf){
  196.     case 0:    /* network PID extension */
  197.         if (thdr[0] == PID_IP && thdr[1] == PID_IP)
  198.             ip_dump(bpp,1) ;
  199.         else
  200.             fprintf(trfp,"         protocol family %x, proto %x",
  201.                     uchar(thdr[0]), uchar(thdr[1])) ;
  202.         break ;
  203.     case 1:    /* Connect request */
  204.         fprintf(trfp,"         conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  205.         pullup(bpp,&x,1);
  206.         fprintf(trfp," wnd %d",x);
  207.         pullup(bpp,(char *)&src,sizeof(struct ax25_addr));
  208.         pax25(tmp,&src);
  209.         fprintf(trfp," %s",tmp);
  210.         pullup(bpp,(char *)&dest,sizeof(struct ax25_addr));
  211.         pax25(tmp,&dest);
  212.         fprintf(trfp,"->%s",tmp);
  213.         break;
  214.     case 2:    /* Connect acknowledgement */
  215.         fprintf(trfp,"         conn ack: ur ckt %d/%d my ckt %d/%d",
  216.             uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
  217.             uchar(thdr[3]));
  218.         pullup(bpp,&x,1);
  219.         fprintf(trfp," wnd %d",x);
  220.         break;
  221.     case 3:    /* Disconnect request */
  222.         fprintf(trfp,"         disc: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  223.         break;
  224.     case 4:    /* Disconnect acknowledgement */
  225.         fprintf(trfp,"         disc ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  226.         break;
  227.     case 5:    /* Information (data) */
  228.         fprintf(trfp,"         info: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  229.         fprintf(trfp," txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
  230.         break;
  231.     case 6:    /* Information acknowledgement */
  232.         fprintf(trfp,"         info ack: ckt %d/%d rxseq %d",
  233.                 uchar(thdr[0]),uchar(thdr[1]),uchar(thdr[3]));
  234.         break;
  235.     default:
  236.         fprintf(trfp,"         unknown transport type %d", thdr[4] & 0x0f) ;
  237.         break;
  238.     }
  239.     if(thdr[4] & 0x80)
  240.         fprintf(trfp," CHOKE");
  241.     if(thdr[4] & 0x40)
  242.         fprintf(trfp," NAK");
  243.     fprintf(trfp,"\n");
  244. }
  245. char *
  246. decode_type(type)
  247. int16 type;
  248. {
  249.     switch(uchar(type)){
  250.     case I:
  251.         return "I";
  252.     case SABM:
  253.         return "SABM";
  254.     case DISC:
  255.         return "DISC";
  256.     case DM:
  257.         return "DM";
  258.     case UA:
  259.         return "UA";
  260.     case RR:
  261.         return "RR";
  262.     case RNR:
  263.         return "RNR";
  264.     case REJ:
  265.         return "REJ";
  266.     case FRMR:
  267.         return "FRMR";
  268.     case UI:
  269.         return "UI";
  270.     default:
  271.         return "[invalid]";
  272.     }
  273. }
  274.  
  275.